import sys

from loguru import logger
from loguru._defaults import env
from tqsdk import TqApi, TqAccount

import trade.s2 as s1

PROT_LOGURU_FORMAT = env(
    "LOGURU_FORMAT",
    str,
    "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
    "<level>{level: <8}</level> | "
    "{message}",
)

logger.remove(handler_id=None)
logger.add(sys.stdout, level="INFO", format=PROT_LOGURU_FORMAT)
logger.add("c:/logs/prot_s2.log", enqueue=True, rotation='1 MB', retention='10 days', encoding="UTF-8")

# api = TqApi(TqSim(), web_gui="http://0.0.0.0:8081")
# api = TqApi(TqAccount(broker_id="B宝城期货", account_id="821000319", password="Ff041002"), web_gui="http://0.0.0.0:8081")
api = TqApi(TqAccount(broker_id="B宝城期货", account_id="882001598", password="Cxc105153"), web_gui="http://0.0.0.0:8082")
# 主动合约
zd_symbol = "SHFE.ss2101"
zd_quote = api.get_quote(zd_symbol)
zd_position = api.get_position(zd_symbol)

# 被动合约
bd_symbol = "SHFE.ss2102"
bd_quote = api.get_quote(bd_symbol)
bd_position = api.get_position(bd_symbol)

# 初始化可开仓位和可平仓位
# pos_total = abs(zd_position.pos)
# logger.info("{0}净持仓（总多-总空）：{1}手", zd_symbol, pos_total)
# s1.trade_strategy["open_volume"] = max(s1.trade_strategy["max_volume"] - pos_total, 0)
# s1.trade_strategy["close_volume"] = min(s1.trade_strategy["max_volume"], pos_total)
logger.info("{0}主动合约策略详情：{1}", zd_symbol, s1.trade_strategy)

# 出现的买卖价差值，出现比预定的买价差小、比卖价差大更新此值为新值，并记录日志；用来验证在命中策略时出现的最小买价差和最大卖价差时是否触发策略，当价差接近时是否动态调整预设策略（TODO）
log_buy_spread = 300
log_sell_spread = 0
while True:
    api.wait_update()
    # 只有行情出现变化时才再次触发策略，防止在同一个已经不存的价差上下单
    if api.is_changing(zd_quote) or api.is_changing(bd_quote):
        buy_spread = zd_quote.ask_price1 - bd_quote.bid_price1
        sell_spread = zd_quote.bid_price1 - bd_quote.ask_price1

        # if buy_spread != log_buy_spread:
        #     log_buy_spread = buy_spread
        #     logger.info("S2策略最新B买价差：{0}，当前设定的开仓买价差：{1}，盘口主动可买开量：{2}，被动可卖开量：{3}，主动合约盘口间隔：{4}，被动合约盘口间隔：{5}", log_buy_spread, s1.open_spread(), zd_quote.ask_volume1,
        #                 bd_quote.bid_volume1,
        #                 zd_quote.ask_price1 - zd_quote.bid_price1, bd_quote.ask_price1 - bd_quote.bid_price1)
        #
        # if sell_spread != log_sell_spread:
        #     log_sell_spread = sell_spread
        #     logger.info("S2策略最新S卖价差：{0}，当前设定的平仓卖价差：{1}，盘口主动可卖平量：{2}，被动可买平量：{3}，主动合约盘口间隔：{4}，被动合约盘口间隔：{5}", log_sell_spread, s1.close_spread(), zd_quote.bid_volume1,
        #                 bd_quote.ask_volume1,
        #                 zd_quote.ask_price1 - zd_quote.bid_price1, bd_quote.ask_price1 - bd_quote.bid_price1)

        # _order_id = _generate_uuid("s1")
        if buy_spread <= s1.open_spread() and s1.open_volume() > 0:
            # 恢复买价差为初始值
            log_buy_spread = 300
            _volume = min(zd_quote.ask_volume1, bd_quote.bid_volume1, s1.open_volume(), s1.max_order_volume())
            logger.info("开仓买价差：{0}，主动合约{1}卖一档{2}，{3}；被动合约{4}买一档{5}，{6}；下单量：{7}", buy_spread, zd_symbol, zd_quote.ask_price1, zd_quote.ask_volume1, bd_symbol, bd_quote.bid_price1,
                        bd_quote.bid_volume1, _volume)

            api.insert_order(symbol=zd_symbol, direction="BUY", offset="OPEN", volume=_volume, limit_price=zd_quote.upper_limit if s1.limit_price else zd_quote.ask_price1)
            api.insert_order(symbol=bd_symbol, direction="SELL", offset="OPEN", volume=_volume, limit_price=bd_quote.lower_limit if s1.limit_price else bd_quote.bid_price1)

            s1.update_left_volume(_volume, "OPEN")
        elif sell_spread >= s1.close_spread() and s1.close_volume() > 0:
            # 恢复卖价差为初始值
            log_sell_spread = 0
            _volume = min(zd_quote.bid_volume1, bd_quote.ask_volume1, s1.close_volume(), s1.max_order_volume())
            logger.info("平仓卖价差：{0}，主动合约{1}买一档{2}，{3}；被动合约{4}卖一档{5}，{6}；下单量：{7}", sell_spread, zd_symbol, zd_quote.bid_price1, zd_quote.bid_volume1, bd_symbol, bd_quote.ask_price1,
                        bd_quote.ask_volume1, _volume)

            _pos_long_today = 0
            # 多头今仓大于0且小于下单量
            if 0 < zd_position.pos_long_today <= _volume:
                _pos_long_today = zd_position.pos_long_today
            # 多头今仓大于0且大于下单量
            elif 0 < zd_position.pos_long_today > _volume:
                _pos_long_today = _volume

            if _pos_long_today > 0:
                api.insert_order(symbol=zd_symbol, direction="SELL", offset="CLOSETODAY", volume=_pos_long_today,
                                 limit_price=zd_quote.lower_limit if s1.limit_price else zd_quote.bid_price1)
            if _volume - _pos_long_today > 0:
                # 剩余平老仓
                api.insert_order(symbol=zd_symbol, direction="SELL", offset="CLOSE", volume=_volume - _pos_long_today,
                                 limit_price=zd_quote.lower_limit if s1.limit_price else zd_quote.bid_price1)

            _pos_short_today = 0
            # 空头今仓大于0且小于下单量
            if 0 < bd_position.pos_short_today <= _volume:
                _pos_short_today = bd_position.pos_short_today
            # 空头今仓大于0且大于下单量
            elif 0 < bd_position.pos_short_today > _volume:
                _pos_short_today = _volume

            if _pos_short_today > 0:
                api.insert_order(symbol=bd_symbol, direction="BUY", offset="CLOSETODAY", volume=_pos_short_today,
                                 limit_price=bd_quote.upper_limit if s1.limit_price else bd_quote.ask_price1)
            if _volume - _pos_short_today > 0:
                api.insert_order(symbol=bd_symbol, direction="BUY", offset="CLOSE", volume=_volume - _pos_short_today,
                                 limit_price=bd_quote.upper_limit if s1.limit_price else bd_quote.ask_price1)

            s1.update_left_volume(_volume, "CLOSE")
